﻿using System;
using System.Collections.Generic;
using BillsDomain;
using System.Xml.Serialization;
using System.IO;

[assembly:CLSCompliant(true)]
namespace BillsDataAccess
{
    /// <summary>
    /// Implementation of a scheduled payment data source that persists to disk.
    /// </summary>
    public class BillsData : IBillsData
    {
        /// <summary>
        /// Path to the data file
        /// </summary>
        private string pathToFile;

        /// <summary>
        /// Initializes a new instance of the BillsData class.
        /// </summary>
        public BillsData()
        {
            this.pathToFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Payment Reminder\\bills.xml");
#if DEBUG
            this.pathToFile = "bills.xml";
#endif
        }

        /// <summary>
        /// Retrieves the payments.
        /// </summary>
        /// <returns>The scheduled payments</returns>
        public List<ScheduledPayment> RetrievePayments()
        {
            List<ScheduledPaymentForSerialization> paymentsForDeserialization = new List<ScheduledPaymentForSerialization>();
            List<ScheduledPayment> payments = new List<ScheduledPayment>();
            XmlSerializer scheduledPaymentsSerializer = new XmlSerializer(typeof(List<ScheduledPaymentForSerialization>));
            if (File.Exists(this.pathToFile))
            {
                using (FileStream fileForReading = new FileStream(this.pathToFile, FileMode.OpenOrCreate))
                {
                    TextReader reader = new StreamReader(fileForReading);
                    paymentsForDeserialization = (List<ScheduledPaymentForSerialization>)scheduledPaymentsSerializer.Deserialize(reader);
                }
            }

            foreach (ScheduledPaymentForSerialization scheduledPayment in paymentsForDeserialization)
            {
                payments.Add(new ScheduledPayment()
                {
                    Amount = scheduledPayment.Amount,
                    FirstDate = scheduledPayment.FirstDate,
                    Id = scheduledPayment.Id,
                    Payee = scheduledPayment.Payee,
                    PaymentRecurrence = Recurrence.FindByName(scheduledPayment.Recurrence),
                    PaymentType = PaymentType.FindByName(scheduledPayment.PaymentType),
                    IncludeInProjection = scheduledPayment.IncludeInProjection
                    //IsDebit = scheduledPayment.PaymentType == PaymentType.Debit.Name
                });
            }

            return payments;
        }

        /// <summary>
        /// Saves the payments.
        /// </summary>
        /// <param name="payments">The scheduled payments.</param>
        public void SavePayments(List<ScheduledPayment> payments)
        {
            if (payments == null)
            {
                throw new ArgumentNullException("payments", "The list of scheduled payments is null.");
            }

            XmlSerializer scheduledPaymentsSerializer = new XmlSerializer(typeof(List<ScheduledPaymentForSerialization>));
            List<ScheduledPaymentForSerialization> forserialization = new List<ScheduledPaymentForSerialization>();
            foreach (ScheduledPayment payment in payments)
            {
                forserialization.Add(new ScheduledPaymentForSerialization()
                {
                    Amount = payment.Amount,
                    FirstDate = payment.FirstDate,
                    Id = payment.Id,
                    Payee = payment.Payee,
                    Recurrence = payment.PaymentRecurrence.Name,
                    PaymentType = payment.PaymentType.Name,
                    IncludeInProjection = payment.IncludeInProjection
                });
            }

            if (!String.IsNullOrEmpty(Path.GetDirectoryName(this.pathToFile)))
            {
                Directory.CreateDirectory(Path.GetDirectoryName(this.pathToFile));
            }

            using (TextWriter fileForWriting = new StreamWriter(this.pathToFile))
            {
                scheduledPaymentsSerializer.Serialize(fileForWriting, forserialization);
            }
        }


        public void SavePayments(List<ScheduledPayment> payments, string pathAndFileName)
        {
            string tempPath = this.pathToFile;
            this.pathToFile = pathAndFileName;
            try
            {
                this.SavePayments(payments);
            }
            finally
            {
                this.pathToFile = tempPath;
            }
        }

        public List<ScheduledPayment> RetrievePayments(string pathAndFileName)
        {
            string tempPath = this.pathToFile;
            this.pathToFile = pathAndFileName;
            try
            {
                return this.RetrievePayments();
            }
            finally
            {
                this.pathToFile = tempPath;
            }
        }
    }
}
